 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using Styx;
using Styx.Combat.CombatRoutine;
using Styx.Helpers;
using Styx.Logic;
using Styx.Logic.Combat;
using Styx.Logic.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

namespace RestorationIce
{
	partial class RestoIce : CombatRoutine
	{
		#region Combat

		private void DungeonCombat()
		{
			tank = GetTank();
			//checkthetank();
			if (unitcheck(tank) < 0) { slog(Color.DarkRed, "Ok, I'm lost, I thought we found a tank, instead I did not, CC is in Pause, please report this Error with full LOG!"); return; }			
			if (healthmon.ElapsedMilliseconds > 50) { healthmoniter(); }
			
			//Enemy = PVEGiveEnemy(29);
			//if (PVE_wanna_target && unitcheck(Enemy) > 0 && (Me.CurrentTarget == null || !Me.CurrentTarget.IsValid || Me.CurrentTarget.Dead)) { if (unitcheck(Enemy) > 0) { Enemy.Target(); } else if (unitcheck(tank.CurrentTarget) > 0) { tank.CurrentTarget.Target(); } }
			//if (Enemy != null) { Enemy.Target(); } else if (tank.CurrentTarget != null) { tank.CurrentTarget.Target(); Enemy = tank.CurrentTarget; }
			if (Interrupt() || StyxWoW.GlobalCooldown) { return; }
			else if (!(Me.Combat) && NeedtoRest()) { slog("resting"); return; }
			else if (PVE_wanna_mount && MountUp()) { return; }
			else if (Self()) { return; }
			else if (rebirth()) { return; }			
			else if (PVE_want_urgent_removecorruption && PVERemoveCorruptionNow()) { return; }
			//Look into possibly making restodruid innterupt maybe when i have nothing better to do...
			//else if (Me.Combat && EnemyInterrupt(PVE_wanna_rebuke, PVE_wanna_HoJ, PVE_wanna_move_to_HoJ)) { return; }
			else if (ManaRec(PVE_min_Innervate_mana)) { return; }
			else if (PVEHealing(PVE_wanna_move_to_heal)) { return; }
			else if (PVE_want_removecorruption && (Me.Combat || !Me.Mounted) && RemovingCorruption()) { return; }
			else if (TopOff()) { return; }
			//else if (Me.Combat && Dps(PVE_wanna_DPS)) { return; }
			//else if (Me.Combat && ConsumeTime(PVE_wanna_Wrath)) { return; }
			else if (PVE_wanna_buff && Buff(PVE_wanna_move_to_heal)) { return; }
			else { }  
			return; 
		}
		private bool RaidCombat()
		{
			DungeonCombat();
			return false;
		}
		private bool SoloCombat()
		{
			DungeonCombat();
			return false;
		}
		private bool RafCombat()
		{
			DungeonCombat();
			return false;
		}
		#endregion

		#region Action       
		private bool PVERemoveCorruptionNow()
		{
			WoWPlayer p = PVEGetUrgentRemoveCorruptionTarget();
			//slog(Color.Violet, "Urgent RemovingCorruption {0}", p.Name);
			return Cast("Remove Corruption", p, 40, "Remove Corruption", "Need Urgent Dispell");
		}

		private bool PVEHealing(bool should_move)
		{			
			if (tar != null && tank != null && tar.IsValid && tank.IsValid && !tar.Dead)
			{
				String s = null;
				double hp = tar.HealthPercent;
				if (tank != null && Me.Mounted && !Me.Combat && !tank.Combat) { return false; } else if (tank == null) { return false; }
				if (tank != null && !Me.Combat && !tar.Combat && tar.Distance > PVE_max_healing_distance) { return false; } else if (tank == null) { return false; }

				if ((Me.HealthPercent < SaveHP) || tank.HealthPercent < SaveHP) { if (Me.HealthPercent < tank.HealthPercent) { tar = Me; slog(Color.LawnGreen, "Changed target to self becuase health is below 40%"); } else if (tank.HealthPercent < Me.HealthPercent) { tar = tank; slog(Color.Crimson, "Changed target to tank becuase health is below 40%");} }
								
				if (myhealthcentlosspersecond >= 4 || tankhealthcentlosspersecond >= 4)
				{
					if (myhealthcentlosspersecond > tankhealthcentlosspersecond) { tar = Me; slog(Color.LawnGreen, "Changed target to self becuase health loss exceeds 4%/s"); }
					else if (tankhealthcentlosspersecond > myhealthcentlosspersecond) { tar = tank; slog(Color.LawnGreen, "Changed target to tank becuase health loss exceeds 4%/s"); }
				}				
				if (should_move && (tar.Distance > 30 || !tar.InLineOfSight)) { slog("Healing target is too far away or not in LOS, moving to them!"); MoveTo(tar); return true; }
			  
				if (hp > 60 ) {goto jump;}
				//=============================================================================================================================================================================                
				if (hp < NS_HT && Me.Combat && !GotBuff("Nature's Swiftness") && CanCast("Nature's Swiftness")) { ChainNSspell(tar.Name, "Healing Touch"); }
				else if (hp < NG_HT && !GotBuff("Nature's Grace") && CanCast("Regrowth", tar) && !(Me.IsMoving) && (!(ng.ElapsedMilliseconds < 45000) || (ng.ElapsedMilliseconds == 0))) { s = "Regrowth"; ng.Reset(); ng.Start(); return Cast(s, tar, 40, "Heal", "Regrowth!"); }
				else if (hp < NG_HT && GotBuff("Nature's Grace") && CanCast("Healing Touch", tar) && !(Me.IsMoving)) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Healing Touch while Nature's Grace is up!"); }
				//Tree of Life
				else if ((hp < TREEIT) && Me.Combat && ShouldAoe(Tree_num, TREEIT) && ShouldTree(Tree_num)) { s = "Tree of Life"; return Cast(s, tar, 40, "Heal", "Got Wood?!"); }
				else if (GotBuff("Tree of Life") && CanCast("Wild Growth")) { tar = Clusters.GetBestUnitForCluster(Unit.NearbyFriendlyPlayers, ClusterType.Radius, 30f); s = "Wild Growth"; return Cast(s, tar, 40, "Heal", "Smart Wild Growth!"); }
				else if (Tranqtree == true && GotBuff("Tree of Life") && CanCast("Tranquility") && !(Me.IsMoving)) { s = "Tranquility"; isinterrumpable = false; return Cast(s, tar, 40, "Heal", "AoE Tranq? "); }
				//End Tree of Life
				else if ((hp < Tranq) && Me.Combat && ShouldAoe(Tranq_num, Tranq) && ShouldTranquility(Tranq_num)) { s = "Tranquility"; isinterrumpable = false; return Cast(s, tar, 40, "Heal", "Saving the world with a tranq!"); }
				else if (hp < NGHT_PostAOE && GotBuff("Nature's Grace") && CanCast("Healing Touch", tar) && !(Me.IsMoving)) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "AoE Checks over now Healing Touch Go!"); }
			jump:
				if (hp < CC_HT && GotBuff("Clearcast") && CanCast("Healing Touch", tar) && !(Me.IsMoving)) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Free Healing Touch Woot!"); }
				else if (hp < CC_RG && GotBuff("Clearcast") && CanCast("Regrowth", tar) && !(Me.IsMoving)) { s = "Regrowth"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "O.o Free Regrowth, gee Thanks!"); }
				//Tank HoT's                
				else if (hp < Tank_HT && tar.Guid == tank.Guid && CanCast("Healing Touch") && !Me.IsMoving) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Healing Touch on the Tank!"); }
				else if (tar.Guid == tank.Guid && CanCast("Lifebloom") && !GotBuff("Lifebloom", tar)) { s = "Lifebloom"; return Cast(s, tar, 40, "Heal", "Tank's missing lifebloom, again..."); }
				else if (tar.Guid == tank.Guid && CanCast("Lifebloom") && GotBuff("Lifebloom", tar) && tar.ActiveAuras["Lifebloom"].StackCount < 3 && tar.Auras["Lifebloom"].CreatorGuid == Me.Guid) { s = "Lifebloom"; return Cast(s, tar, 40, "Heal", "Tank missing triple LB, giving him somemore lifeboom now!"); }                
				else if (tar.Guid == tank.Guid && CanCast("Lifebloom") && GotBuff("Lifebloom", tar) && tar.ActiveAuras["Lifebloom"].TimeLeft.TotalMilliseconds <= 1500 && hp > 40 && tar.Auras["Lifebloom"].CreatorGuid == Me.Guid) {  s = "Lifebloom"; return Cast(s, tar, 40, "Heal", "Refreashing the Tank's Lifeboom before he drops.. tick tick tick...!") ;  }
				else if (hp < Tank_Rejuv && tar.Guid == tank.Guid && CanCast("Rejuvenation", tar) && !GotBuff("Rejuvenation", tar)) { s = "Rejuvenation"; return Cast(s, tar, 40, "Heal", "Tank's getting tired hears a rejuvenation..."); }
				//End of Tank HoT's
				else if (hp < SM && CanCast("Rejuvenation", tar) && (GotBuff("Rejuvenation", tar) || GotBuff("Regrowth", tar))) { s = "Swiftmend"; return Cast(s, tar, 40, "Heal", "Swiftmend, for the instant heal!"); }
				else if ((hp < WG_min_hp) && ShouldAoe(WG_Num, WG_min_hp) && ShouldWildGrowth(WG_Num) && CanCast("Wild Growth", tar)) { tar = Clusters.GetBestUnitForCluster(Unit.NearbyFriendlyPlayers, ClusterType.Radius, 30f); s = "Wild Growth"; return Cast(s, tar, 40, "Heal", "Smart Wild Growth Again!"); }
				else if ((hp < Efflo_min_hp) && ShouldAoe(Efflo_Num, Efflo_min_hp) && ShouldEfflorescence(Efflo_Num) && CanCast("Swiftmend", tar)) { tar = Clusters.GetBestUnitForCluster(Unit.NearbyFriendlyPlayers, ClusterType.Radius, 8f); s = "Swiftmend"; return Cast(s, tar, 40, "Heal", "Oooo. smart Efflorescece!"); }
				else if (hp < Rejuv && CanCast("Rejuvenation", tar) && !GotBuff("Rejuvenation", tar)) { s = "Rejuvenation"; return Cast(s, tar, 40, "Heal", "Rejuv the slacker"); }
				else if (hp < HT && CanCast("Healing Touch", tar) && !(Me.IsMoving)) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Healing Touch.. Again...!"); }
				else if (tar.Guid == tank.Guid && hp < HT + 10 && CanCast("Healing Touch", tar) && !(Me.IsMoving)) { s = "Healing Touch"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Tanks when will they learn...!"); }
				else if (hp < Nourish && CanCast("Nourish", tar) && (GotBuff("Rejuvenation", tar) || GotBuff("Regrowth", tar) || GotBuff("Wild Growth", tar) || GotBuff("Lifebloom", tar))) { s = "Nourish"; isinterrumpable = true; return Cast(s, tar, 40, "Heal", "Nourish for the noobish Hottie!"); }
				//=============================================================================================================================================================================
				

				return false;
			}
			else
			{
				return false;
			}
		}

		#endregion
		
		#region Helpers

		private WoWUnit PVEGiveEnemy(int distance)
		{
			WoWUnit enemy = (from unit in ObjectManager.GetObjectsOfType<WoWUnit>(false, false)
							 where unit.IsHostile
							 where !unit.Dead
							 where (tank!=null && tank.CurrentTargetGuid == unit.Guid)
							 where unit.Distance < distance
							 where unit.InLineOfSight
							 select unit
							).FirstOrDefault();
			return enemy;
		}

		private bool PVEOhShitButton()
		{
			if (!GotBuff("Barkskin"))
			{
				if (PVE_wanna_BS && CanCast("Barksin")) 
				{     
				//    slog(Color.Black, "Oh Shit! Casting Avenging Wrath"); 
					return Cast("Barksin", "OhShit", "Make sure interruptions aren't an issue");
				}               
			}
			return false;
		}

		private WoWPlayer PVEGetUrgentRemoveCorruptionTarget()
		{
			return (from unit in ObjectManager.GetObjectsOfType<WoWPlayer>(true, true)
					orderby unit.HealthPercent ascending
					where !unit.Dead
					where !unit.IsGhost
					where unit.Distance < 80
					where (unit.IsInMyPartyOrRaid || unit.IsMe)
					where PVENeedsUrgentRemoveCorruption(unit)
					select unit).FirstOrDefault();
		}

		private bool PVENeedsUrgentRemoveCorruption(WoWPlayer p)
		{

			foreach (WoWAura a in p.ActiveAuras.Values)
			{
				if (
					(p.ActiveAuras.ContainsKey("Static Cling")) ||
					(p.ActiveAuras.ContainsKey("Flame Shock")) ||
					(p.ActiveAuras.ContainsKey("Static Discharge")) ||
					(p.ActiveAuras.ContainsKey("Consuming Darkness")) ||
					(p.ActiveAuras.ContainsKey("Lash of Anguish")) ||
					(p.ActiveAuras.ContainsKey("Static Disruption")) ||
					(p.ActiveAuras.ContainsKey("Fear"))
				   )
				{
					WoWDispelType t = a.Spell.DispelType;
					if (t == WoWDispelType.Curse || t == WoWDispelType.Magic || t == WoWDispelType.Poison)
					{
						return true;
					}
				}
			}
			return false;
		}

		#endregion
	}
}